/**
 * 
 */
package cyber2d.core.objects.act;

//phys2d
import net.phys2d.math.Vector2f;
import net.phys2d.raw.CollisionEvent;
import net.phys2d.raw.World;
import net.phys2d.raw.shapes.Box;
//cyber2d
import cyber2d.core.objects.Creature;
import cyber2d.core.objects.Shot;
import cyber2d.core.objects.Tile;

/**
 * A activator (collider) factory to create activators  
 * for objects in game world (UniverseObjects).
 * 
 * @author Meraxupypr (Konstantin Petrukhnov)
 * 19.04.2007   23:41:23
 * 
 */
public class ActivatorFactory
{
	
	World world;
	
	//constructor
	public ActivatorFactory (World world)
	{
		this.world = world;
	}
	
	/**
	 * this method used to prevent dublicates of act pairs:
	 * e.g (Creature,Shot) and (Shot,Creature)
	 * * so it works like some sorting mechanism
	 */
	public Activator createActivator(CollisionEvent ce)
	{
			//set of ifs
		//if first object is Shot
		if (ce.getBodyA().getUserData() instanceof Shot)
		{
			//if second object is Shot
			if (ce.getBodyB().getUserData() instanceof Shot)
			{
				return createActivatorFor(ce, (Shot) ce.getBodyA().getUserData(), (Shot) ce.getBodyB().getUserData());
			}
			//if second object is Creature
			if (ce.getBodyB().getUserData() instanceof Creature)
			{
				return createActivatorFor(ce, (Shot) ce.getBodyA().getUserData(), (Creature) ce.getBodyB().getUserData());
			}
			//if second object is Tile
			if (ce.getBodyB().getUserData() instanceof Tile)
			{
				return createActivatorFor(ce, (Shot) ce.getBodyA().getUserData(), (Tile) ce.getBodyB().getUserData());
			}
		}
		//if first object is Creature
		else if (ce.getBodyA().getUserData() instanceof Creature)
		{
			//if second object is Shot
			if (ce.getBodyB().getUserData() instanceof Shot)
			{
				return createActivatorFor(ce, (Shot) ce.getBodyB().getUserData(), (Creature) ce.getBodyA().getUserData()); 
			}
			//if second object is Creature
			if (ce.getBodyB().getUserData() instanceof Creature)
			{
				return createActivatorFor(ce, (Creature) ce.getBodyA().getUserData(), (Creature) ce.getBodyB().getUserData()); 
			}
			//if second object is Tile
			if (ce.getBodyB().getUserData() instanceof Shot)
			{
				return createActivatorFor(ce, (Creature) ce.getBodyA().getUserData(), (Tile) ce.getBodyB().getUserData()); 
			}
		}
		//if first object is Tile
		else if (ce.getBodyA().getUserData() instanceof Tile)
		{
			//if second object is Shot
			if (ce.getBodyB().getUserData() instanceof Shot)
			{
				return createActivatorFor(ce, (Shot) ce.getBodyB().getUserData(), (Tile) ce.getBodyA().getUserData()); 
			}
			//if second object is Creature
			if (ce.getBodyB().getUserData() instanceof Creature)
			{
				return createActivatorFor(ce, (Creature) ce.getBodyB().getUserData(), (Tile) ce.getBodyA().getUserData()); 
			}
		}
		
		//throw exception if no suitable Activator
		return null;
	}
	

	// Shot Shot
	public Activator createActivatorFor(CollisionEvent ce,Shot shotA, Shot shotB)
	{
		//remove shots
		world.remove(ce.getBodyA());
		world.remove(ce.getBodyB());
		
		return new ShotShotActivator();
	}
	
	// Shot Creature
	public Activator createActivatorFor(CollisionEvent ce,Shot shotA, Creature creatureB)
	{
		//decrease hp of creature according to shot damage
		creatureB.hpCur -= shotA.damage; 
			//destroy shot (animation or something other)
		//define shot, and destroy it
		if (ce.getBodyA().getUserData() instanceof Shot)
		{
			world.remove(ce.getBodyA()); //if Shot is A - remove it
		}
		else world.remove(ce.getBodyB()); //else it is B, so remove it
		
		//return activator
		return new ShotCreatureActivator();
	}
	
	// Shot Tile
	public Activator createActivatorFor(CollisionEvent ce,Shot shotA, Tile tileB)
	{
		//define shot, and destroy it
		if (ce.getBodyA().getUserData() instanceof Shot)
		{
			world.remove(ce.getBodyA()); //if Shot is A - remove it
		}
		else world.remove(ce.getBodyB()); //else it is B, so remove it
		
		return new ShotTileActivator();
	}
	
	// Creature Creature	
	public Activator createActivatorFor(CollisionEvent ce, Creature creatureA, Creature creatureB)
	{
		// TODO Auto-generated method stub
		return new CreatureCreatureActivator();
	}
	
	// Creature Tile
	public Activator createActivatorFor(CollisionEvent ce,Creature creatureA, Tile tileB)
	{
		//if collide bottom edge (but not corners):
		
		//collision position
		float pointPosY = ce.getPoint().getY();
		
		Box box = (Box) creatureA.body.getShape(); //creature shape
		Vector2f[] pts = box.getPoints(creatureA.body.getPosition(), creatureA.body.getRotation()); //get points
		
		// Y coordinate of bottom edge
		float creatureBottomEdgePos = creatureA.body.getPosition().getY() + box.getSize().getY()/2;
		
		//int creaturePosX = (int) (uoA.body.getPosition().getX() + box.getSize().getX()/2);
		//System.out.println(pointPos + "   " + creaturePos);
		float abc = Math.abs(pointPosY-creatureBottomEdgePos);
		
		if ((abc<2)
			/*&&
			(ce.getPoint().getX() >
				(uoA.body.getPosition().getX() - box.getSize().getX()/2))
			&&
			(ce.getPoint().getX()<
				(uoA.body.getPosition().getX() + box.getSize().getX()/2))*/
			)
		{
			//System.out.println("foot");
			creatureA.nOfBottomCollisions++;
		}
		
		return new CreatureTileActivator();
	}
	

	
}
